package com.common.base;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.vo.ExceptionVo;
import com.entity.sys.SysUser;
import com.entity.sys.query.SysQuery;

import java.util.HashMap;
import java.util.Map;

public abstract class BaseService<M extends BaseMapper<E>, E extends BaseEntity> extends ServiceImpl<M, E>{

    /**
     * 获取当前登录的用户
     */
    public SysUser getCurrentUser(){
        SysUser user = (SysUser) StpUtil.getSession().get("user");
        if (user == null){
            throw new ExceptionVo(1003,"用户未登录");
        }
        return user;
    }

    /**
     * 系统设置模块统一的传参参数设置（这里的参数用于自定义的查询语句）
     */
    public Map<String,Object> sysParams(SysQuery queryVo){
        Map<String,Object> map = new HashMap<>();
        if (StrUtil.isNotBlank(queryVo.getId())){
            map.put("id",queryVo.getId());
        }
        if (StrUtil.isNotBlank(queryVo.getParentId())){
            map.put("parentId",queryVo.getParentId());
        }
        if (StrUtil.isNotBlank(queryVo.getName())){
            map.put("name",queryVo.getName());
        }
        if (StrUtil.isNotBlank(queryVo.getCode())){
            map.put("code",queryVo.getCode());
        }
        if (queryVo.getState() != null){
            map.put("state",queryVo.getState());
        }
        if (StrUtil.isNotBlank(queryVo.getStartDate())){
            map.put("startDate",queryVo.getStartDate());
        }
        if (StrUtil.isNotBlank(queryVo.getEndDate())){
            map.put("endDate",queryVo.getEndDate());
        }
        SysUser user = getCurrentUser();
        if (user.getQueryDataScope() != null){
            map.putAll(user.getQueryDataScope());
        }
        return map;
    }

    /**
     * 根据 当前用户的数据范围 拼接查询条件语句（这里拼接的查询条件用于单表 QueryWrapper 查询）
     * @param fieldName  查询的字段名
     * @param createBy   查询本人数据时使用的的字段名
     * @param type       拼接的条件是取 部门id 还是 部门name（1 id 2 name）
     */
    public String queryApplyScope(String fieldName,String createBy,int type){
        StringBuilder sqlString = new StringBuilder();
        SysUser user = getCurrentUser();
        if (user.getQueryDataScope() != null){
            Map<String, String> scope = user.getQueryDataScope();
            if (type == 1){ // 用部门id字段过滤
                if (StrUtil.isNotBlank(scope.get("dataScope"))){ // 这里不为空，说明数据范围是 5（自定义数据）
                    // 5 和其他数字的范围取并集，用 or 连接，并且它们的外层不要忘了用括号括起来
                    sqlString.append(StrUtil.format("(FIND_IN_SET({},'{}')",fieldName, scope.get("customId")));
                    if (StrUtil.isNotBlank(scope.get("deptAndSubId"))) {
                        sqlString.append(StrUtil.format(" or FIND_IN_SET({},'{}')",fieldName, scope.get("deptAndSubId")));
                    }else if (StrUtil.isNotBlank(scope.get("deptId"))){
                        sqlString.append(StrUtil.format(" or {} = '{}'",fieldName, scope.get("deptId")));
                    }
                    sqlString.append(")");
                }else {
                    // 拼接条件为 部门id时，所在部门及子部门数据用 FIND_IN_SET 查询；所在部门数据直接用等于查询；
                    if (StrUtil.isNotBlank(scope.get("deptAndSubId"))) {
                        sqlString.append(StrUtil.format("FIND_IN_SET({},'{}')",fieldName, scope.get("deptAndSubId")));
                    }else if (StrUtil.isNotBlank(scope.get("deptId"))){
                        sqlString.append(StrUtil.format("{} = '{}'",fieldName, scope.get("deptId")));
                    }
                }
            }else { // 用部门名称字段过滤
                if (StrUtil.isNotBlank(scope.get("dataScope"))){
                    sqlString.append(StrUtil.format("(FIND_IN_SET({},'{}')",fieldName, scope.get("customName")));
                    if (StrUtil.isNotBlank(scope.get("deptAndSubName"))) {
                        sqlString.append(StrUtil.format(" or FIND_IN_SET({},'{}')",fieldName, scope.get("deptAndSubName")));
                    }else if (StrUtil.isNotBlank(scope.get("deptName"))){
                        sqlString.append(StrUtil.format(" or {} = '{}'",fieldName, scope.get("deptName")));
                    }
                    sqlString.append(")");
                }else {
                    // 拼接条件为 部门name时，所在部门及子部门数据用 FIND_IN_SET 查询；所在部门数据直接用等于查询；
                    if (StrUtil.isNotBlank(scope.get("deptAndSubName"))){
                        sqlString.append(StrUtil.format("FIND_IN_SET({},'{}')",fieldName, scope.get("deptAndSubName")));
                    }else if (StrUtil.isNotBlank(scope.get("deptName"))){
                        sqlString.append(StrUtil.format("{} = '{}'",fieldName, scope.get("deptName")));
                    }
                }
            }
            // 这里还要判断 createBy 字段不为空，是因为有的表它不需要根据本人过滤，只用根据部门过滤
            if (StrUtil.isNotBlank(createBy) && StrUtil.isNotBlank(scope.get("createBy"))){
                // 仅本人数据直接用等于查询；
                if (StrUtil.isNotBlank(sqlString)){
                    sqlString.append(StrUtil.format(" and {} = '{}'",createBy, scope.get("createBy")));
                }else {
                    sqlString.append(StrUtil.format("{} = '{}'",createBy, scope.get("createBy")));
                }
            }
        }
        return sqlString.toString();
    }

}
